package com.rivues.core;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.core.CoreContainer;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.rivu.handler.GeneraDAO;
import org.springframework.web.context.WebApplicationContext;

import com.rivues.module.platform.web.model.JobDetail;
import com.rivues.module.platform.web.model.SearchResultTemplet;
import com.rivues.module.platform.web.model.User;
import com.rivues.task.resource.DataExchangeResource;
import com.rivues.task.resource.DatabaseResource;
import com.rivues.task.resource.EventTaskResource;
import com.rivues.task.resource.ExportReportResource;
import com.rivues.task.resource.LocalShellResource;
import com.rivues.task.resource.ReportResource;
import com.rivues.util.RivuTools;
import com.rivues.util.exception.RivuException;
import com.rivues.util.service.cache.CacheHelper;
import com.rivues.util.service.data.RequestStaticisBean;


@SuppressWarnings("rawtypes")
public class RivuDataContext {
	public static boolean cluster = true ;
	private final static String DAO_NAME = "dao" ;
	public final static String USER_SESSION_NAME = "user" ;
	public static final String PLUGIN_TYPE_TASK = "task" ;
	public static final String TABLE_NAME_DEFAULT = "r3_tab" ;
	public static final String GUEST_USER = "Guest" ;
	public static final String REFER_STR = "referer" ;
	public static final String DATA_M_DEFAULT = "r3_datam" ;
	public static final String FILE_SPLIT_LINE = " BEGIN----------------------FILE_SPLIT_LINE----------------------------END " ;
	public static final String PLUGIN_TYPE_INDEX_PROCESS = "indexprocess" ;
	public static String SAVE_FILE_DIR = "/WEB-INF/data/file" ;
	public static String SERVER_ADDRESS ="platform.server.address";
	public static String DATA_DIR = "/WEB-INF/data";
	public static final String JDBC_R3 = "jdbc:r3:" ;
	public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd" ;
	public static final String CHILD_DIM_PREFIX = "CHILD_" ;
	public static final String INIT_SCRIPT_FILE_EXT_NAME = ".data" ;
	public static final String R3_SYSTEM = "R3_SYSTEM" ;
	public static final String DEFAULT_VALIUE_SPLIT = "  ,  ";
	public static final String WEB = "web";
	public static final String LOG_TYPE_DEFAULT = "log_def";
	public static final String MODEL = "model";
	public static final String HANDLER = "handler";
	public static String TPL_DIR = "/WEB-INF/view";
	public static final String ALL_USER_CH = "所有人" ;
	public static final String CUBE_TITLE_MEASURE = "指标" ;
	public static final String JOB_REPORT_ID = "JOB_" ;
	public static final String ALL_USER_EN = "All" ;
	public static final int EXPORT_PAGE_SIZE = 5000 ;				//Export Data Per Page size 
	public static final int DEFAULT_MAIL_MAX_PAGE_SIZE = 200 ;
	public static String REAL_PATH;
	private static boolean start  = false;
	private static boolean stoppint = false ;
	private static final Date startTime = new Date();
	private static GeneraDAO service ;
	private static EmbeddedSolrServer solrservice;
	private static WebApplicationContext wac;
	private static CoreContainer corecontainer ;
	private final static String START_ID = String.valueOf(System.currentTimeMillis()) ;
	private static final String SHIRO_SESSION_DAO = "shiroSessionDAO";
	public static Map<String , Class> resourceMap = new HashMap<String , Class>() ;
	private static Map<String ,JobDetail> localRunningJob = new HashMap<String , JobDetail>();
	private static String serverName ;
	
	public final static String CACHE_TPL_DIC = "cache_tpl_dic" ;
	public final static String CACHE_TPLRESULT_LIST = "cache_tpl_result_list" ;
	
	private static ConcurrentMap<String , RequestStaticisBean> requestStaticisBeanMap = new ConcurrentHashMap<String , RequestStaticisBean>() ;
	
	static{
		resourceMap.put("table", DatabaseResource.class) ;
		resourceMap.put("report", ReportResource.class) ;
		resourceMap.put("dataex", DataExchangeResource.class) ;
		resourceMap.put("process", LocalShellResource.class) ;
		resourceMap.put("event", EventTaskResource.class) ;
		resourceMap.put("export", ExportReportResource.class) ;
		
		ConvertUtils.register(new DateConverter(null), java.util.Date.class);   
	}
	/**
	 * 
	 */
	public static void initR3ContextData(){
		/**
    	 * 将模板的内容放到 报表设计的页面上
    	 */
		CacheHelper.getDistributedDictionaryCacheBean().put(InitDataContext.TEMPLETLIST.toString() , getService().findAllByCriteria(DetachedCriteria.forClass(SearchResultTemplet.class)
				.addOrder(Order.asc("createtime")).add(Restrictions.or(Restrictions.eq("templettype", TempletType.CHART.toString()), Restrictions.eq("templettype", TempletType.REPORTMODULE.toString())))) , "SYSTEM");//只加载 HTML组件和 图表组件
		CacheHelper.getDistributedDictionaryCacheBean().put(
				InitDataContext.TYPECATEGORY.toString(),
				getService().findAllByCriteria(
						DetachedCriteria.forClass(com.rivues.module.platform.web.model.TypeCategory.class)
								.addOrder(Order.asc("createtime"))
								.add(Restrictions.eq("ctype", TempletType.REPORTMODULE.toString()))) , "SYSTEM");
		CacheHelper.getDistributedDictionaryCacheBean().put(
				InitDataContext.CHARTCATEGORY.toString(),
				getService().findAllByCriteria(
						DetachedCriteria.forClass(com.rivues.module.platform.web.model.TypeCategory.class)
								.addOrder(Order.asc("createtime"))
								.add(Restrictions.eq("ctype", TempletType.CHART.toString()))) , "SYSTEM");
    	
	}
	/**
	 * 
	 * @param resource
	 * @return
	 */
	public static Class getResource(String resource){
		return resourceMap.get(resource) ;
	}
	/**
	 * 系统级的加密密码 ， 从CA获取
	 * @return
	 */
	public static String getSystemSecrityPassword(){
		return "123456" ;
	}
	/**
	 * 服务器系统监测
	 * @author admin
	 *
	 */
	public enum SystemInfoType{
		R3QUERY_SERVER,
		DATABASE_SERVER,
		HADOOP_SERVER,
		RIVUES_SERVER, 
		R3QUERY_V50_SERVER;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	//系统不可用类型
	public enum UnavailableTypeEnum{
		SERVERDOWN ,
		SERVICEDOWN;

		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	//邮件类型
	public enum EmailTypeEnum{
		TEST ,
		PUBLISH , 
		SUBSCRIPTION;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	//邮件类型
	public enum TypeCategory{
		CUBE ,
		CHART,
		TEMPLET ;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	//模型目录类型
	public enum TableDirType{
		METADATA ,
		CUBE ;

		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	//模型目录类型
	public enum TabType{
		PUB ,
		PRI ;

		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	//模板类型
	public enum TempletType{
		REPORT ,
		REPORTMODULE,
		CHART,
		DATAV,
		SYSTEM
		;

		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	//模板类型
	public enum SystemSettingType{
		SERVICE ,
		SECRITY,
		PARAM,
		STORAGE,
		LOG,
		QUOTA,
		CACHE;
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}

	//日志类型
	public enum LogCategoryEnum{
		OPERATE ,
		SYSTEM , 
		LOGIN,
		REPORT ;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	//日志类型
		public enum ErrorMessageCode{
			ERR_1000000("ERR_1000000", "未知账户"),
			ERR_1000001("ERR_1000001", "密码不正确"),
			ERR_1000002("ERR_1000002", "账户已锁定"), 
			ERR_1000003("ERR_1000003", "用户名或密码错误次数过多"),
			ERR_1000004("ERR_1000004", "用户名或密码不正确") ;
			
			private String code ;
			private String text ;
			private ErrorMessageCode(String code , String text){
				this.code = code ;
				this.text = text ;
			}
			
			public String getCode() {
				return code;
			}

			public void setCode(String code) {
				this.code = code;
			}

			public String getText() {
				return text;
			}

			public void setText(String text) {
				this.text = text;
			}

			public String toString(){
				return super.toString().toLowerCase() ;
			}
		}
	
	//条件类型
	public enum FilterEnum{
		DIMENSION ,
		REPORT;

		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}	

	//条件类型
	public enum FilterConValueEnum{
		INPUT ,
		AUTO,
		USERDEF;

		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}	
	//记录日志小分�?
	public enum LogTypeEnum{
		REQUEST,
		CREATE ,
		READ , 
		UPDATE,
		DELETE,
		OTHER,
		INFO,
		WARN,
		ERROR
		;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum TypeCategoryEnum{
		TEMPLET ,
		CUBE , 
		CHART,
		REPORT ;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum ReportModelTypeEnum{
		VIEW ,
		CHART , 
		MODEL ;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum InitDataContext{
		TYPECATEGORY ,
		CHARTCATEGORY ,
		TEMPLETLIST;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum SCHEMA_VERSION{
		R3_QUERY_VERSION_4,
		R3_QUERY_VERSION_5;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum EventType{
		MEMBERREMOVE ,
		MEMBERADDED,
		JOBDETAIL,
		REPORTJOB,
		NOEMAILCONFIG,
		STORAGESPACE;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum EventLevelType{
		CRITICAL,		//危急
		ERROR,			//错误
		WARNING,		//警告
		INFORMATIONAL;	//提示
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum FilterConType{
		DIMENSION,
		MEASURE;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum FilterCompType{
		NOT,
		EQUAL;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum FilterConValueType{
		INPUT,
		AUTO,
		USERDEF;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum FilterModelType{
		TEXT,
		DATE,
		SIGSEL,
		SELECT;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum FilteFunType{
		FILTER,
		RANK;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum ConfigParamEnum{
		AUTH;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum NotifiactionType{
		EMAIL,
		SMS;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum ReportStatusEnum{
		NEW,
		PUBLISHED ,
		AVAILABLE,
		UNAVAILABLE;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum ReportTypeEnum{
		REPORT,
		PLAN,
		SHORTCUTS ,
		SAVEAS,
		ADHOC("0"),		//自助查询
		CUSREPORT("1"),	//动态报表
		DASHBOARD,
		PAGE;	//DASHBOARD
		ReportTypeEnum(){
			
		}
		private String type ;
		ReportTypeEnum(String type){
			this.type = type ;
		}
		public String getType() {
			return type;
		}

		public void setType(String type) {
			this.type = type;
		}

		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum ReportCompareEnum{
		RANGE,
		COMPARE,
		START,
		END;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	public enum QueryLogEnum{
		REPORT,
		MODEL,
		DATABASE;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	/**
	 * 任务状态
	 * @author admin
	 *
	 */
	public enum TaskStatusType{
		NORMAL("0"),
		READ("1"),
		RUNNING("2");
		private String type ;
		
		TaskStatusType(String type){
			this.type = type ;
		} 
		public String getType() {
			return type;
		}

		public void setType(String type) {
			this.type = type;
		}

		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	/**
	 * 任务状态
	 * @author admin
	 *
	 */
	public enum TaskResultType{
		SUCCESS(1),
		FAILD(2),
		CANCLE(3),
		UNKNOW(0);
		private int type ;
		
		TaskResultType(int type){
			this.type = type ;
		} 

		public int getType() {
			return type;
		}


		public void setType(int type) {
			this.type = type;
		}


		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum SystemLogType{
		START,
		STOP,
		RESTART;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	public enum TaskTypeEnum{
		CUBEDATA ,
		TABLE , 
		PUBLISH ,
		DATAEX,		//数据迁移
		EVENT,
		EXPORT,
		REPORT,
		PROCESS;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	public enum TemplateNameEnum{
		web ,
		applicationContext , 
		springServlet,
		JavaBean ;
		
		public String toString(){
			return super.toString() ;
		}
	}
	/**
	 * 高速缓存的对象名称
	 * @author admin
	 *
	 */
	public enum CacheNameEnum{
		CACHE_DISTRIBUTED_MAP,
		CACHE_DICTIONARY_MAP,
		CACHE_DISTRIBUTED_REPORT_DATA,
		CACHE_DISTRIBUTED_SESSION;
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum DistributeEventEnum{
		MEMBERDISTRIBUTEDEVENT("member-distributed-event"),
		MEMBERLOCKEVENT("member-distributed-lock"),
		JOBDETAILOCK("jobdetail-distributed-lock"),
		EVENTDISTRIBUTEQUEUE("event-distributed-queue"),
		DATASOURCEDISTRIBUTEDEXECUTOR("datasource-distributed-executor"),
		SYSTEMSTATICISBEAN("staticis-distributed-executor"),
		SERVERCONTROL("servercontrol-distributed-executor"),
		JOBDETAIL("jobdetail-distributed-executor"),
		RUNNINGJOB("runningjob-distributed-executor"),
		RUNNINGJOBREPORT("runningjobreport-distributed-executor");
		
		private String value ;
		
		DistributeEventEnum(String value){
			this.value = value ;
		}
		public String getValue() {
			return value;
		}

		public void setValue(String value) {
			this.value = value;
		}

		public String toString(){
			return this.value ;
		}
	}
	public enum CubeEnum{
		CUBE ,
		TABLE,
		R3;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum SearchType{
		ALL,
		DIC,
		CREATE,			//我创建的报表
		SAVE;			//我保存的报表
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum TaskNodeTypeEnum{
		MAIL ,
		SMS,
		FILE,
		ROUTE,
		URL;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	public enum QueryReportDragEnum{
		DIMENSIONS ,
		MEASURE;
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	public enum DataBaseTYPEEnum{
		MYSQL ,
		ORACLE,
		R3,
		SQLSERVER,
		POSTGRESQL , 
		HIVE; 
		
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	/**
	 * 系统级参数
	 * @author admin
	 *
	 */
	public enum SystemParamEnum{
		DATAPROCESS("com.rivues.service.monitor.dataprocess.sql"),
		USERAUTHCLASS("com.rivues.user.auth.api"),
		SHORT_MESSAGE_CLASS("com.rivues.tools.sms.send"),//短信处理类
		ACCOUNTSERVICECLASS("com.rivues.module.manage.web.service.accountservice"),
		TOTALCOLCLASSNAME("com.rivues.report.col.total.classname"),
		DATASOURCE("R3_BigData_Default_DataSrouce");
		private String value = "";
		
		private SystemParamEnum(String value){
			this.value = value!=null ? value : "" ;
		}
		public String getValue() {
			return value;
		}

		public void setValue(String value) {
			this.value = value;
		}

		public String toString(){
			return this.value.toLowerCase() ;
		}
	}
	
	public enum ConnectionTypeEnum{
		JDBC ,
		JNDI,
		ODBC; 
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum DataFillTypeEnum{
		CACHE ,
		DATASOURCE; 
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum DrillDownTypeEnum{
		URL ,
		DETAIL,
		REPORT; 
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum DrillDownPosEnum{
		DIM ,
		NEWCOL,
		MEASURE; 
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum ReportNewColType{
		CUR ,
		NEXT; 
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	
	public enum AuthTypeEnum{
		DIC,
		REPORT; 
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	
	public enum UserTypeEnum{
		SUPER("0");
		
		private String value = "0";
		
		UserTypeEnum(String value){
			this.value = value!=null ? value : "" ;
		}
		public String getValue() {
			return value;
		}

		public void setValue(String value) {
			this.value = value;
		}

		public String toString(){
			return this.value.toLowerCase() ;
		}
	}
	
	public enum ServiceTypeName{
		LOG,
		REPORT,
		CUBE,
		DATABASE,
		DATASOURCE,
		DISTRIBUTE_DATASOURCE,
		STATICIS_DATA,
		SYSTEM_EVENT,
		SYSTEM_MONITOR,
		SERVER_CONTROL,
		JOB_DETAIL,
		EXPORT_FILE; 
		public String toString(){
			return super.toString().toLowerCase() ;
		}
	}
	private static Map<String , Map<String , Object>> objectTargetMap = new HashMap<String , Map<String , Object>>() ;
	static{
		objectTargetMap.put(DistributeEventEnum.RUNNINGJOB.toString(), new HashMap()) ;
		objectTargetMap.put(DistributeEventEnum.RUNNINGJOBREPORT.toString(), new HashMap()) ;
		objectTargetMap.put(DistributeEventEnum.JOBDETAIL.toString(), new HashMap()) ;
		
	}
	/**
	 * 
	 * @return
	 */
	public static Map<String , Map<String , Object>> getClusterInstance(){
		return objectTargetMap ;
	}
	public static void setWac(WebApplicationContext webApplicationContext) {
		wac = webApplicationContext ;
	}
	public static GeneraDAO getService(){
		return service==null ? (GeneraDAO)wac.getBean(DAO_NAME) : service;
	}
	
	
	public static EmbeddedSolrServer getSolrService()throws RivuException{
		if(solrservice==null){
			if(corecontainer!=null){
				solrservice = new EmbeddedSolrServer(corecontainer, "rivues");
			}else{
				throw new RivuException("SOLR_ERR_00001");
			}
			
		}
		return solrservice;
	}
	/**
	 * 
	 * @return
	 */
	public static WebApplicationContext getWebApplicationContext(){
		return wac;
	}
	/**
	 * 返回当前系统所有在线用户
	 * @return
	 */
	public static List<User> getOnlineUser(){
		SessionDAO sessionDAO = (SessionDAO) wac.getBean(RivuDataContext.SHIRO_SESSION_DAO) ;
		Collection<Session> sessiones = sessionDAO.getActiveSessions() ;
		List<User> userList= new ArrayList<User>() ;
		if(sessiones!=null){
			for(Session session : sessiones){
				userList.add((User) session.getAttribute(RivuDataContext.USER_SESSION_NAME));
			}
		}
		return userList ;
	}
	
	public static User getUser(HttpServletRequest request){
		Object session = request.getSession(true);
		User user = null;
		if(session!=null){
			Object obj_user = ((HttpSession)session).getAttribute(RivuDataContext.USER_SESSION_NAME);
			if(obj_user==null){
				user = new User();
				user.setUsername("Guest") ;
				user.setId(RivuTools.md5(request.getSession(true).getId())) ;
			}else{
				user = (User)obj_user;
			}
		}else{
			user = new User();
			user.setUsername("Guest") ;
			user.setId("Guest_"+System.currentTimeMillis()) ;
		}
		if(request.getSession(true)!=null){
			user.setSessionid(request.getSession(true).getId()) ;
		}else{
			user.setSessionid("Guest_session_"+System.currentTimeMillis());
		}
		
		return user ;
	}
	
	public static void setCorecontainer(CoreContainer cores) {
		corecontainer = cores ;
	}
	
	public static CoreContainer getCorecontainer() {
		return corecontainer;
	}
	public static boolean isStart() {
		return start;
	}
	public static void setStart(boolean start) {
		RivuDataContext.start = start;
	}
	
	public static String getSystemStartID(){
		return START_ID ;
	}
	public static Date getStartTime() {
		return startTime;
	}
	public static boolean isStopping(){
		return stoppint ;
	}
	public static void setStopping() {
		RivuDataContext.stoppint = true ;
	}
	public static ConcurrentMap<String , RequestStaticisBean> getStaticServiceMap(){
		return requestStaticisBeanMap ;
	}
	
	public static SessionDAO getSessionDao(){
		return wac.getBean(SHIRO_SESSION_DAO,SessionDAO.class);
	}
	public static Map<String, JobDetail> getLocalRunningJob() {
		return localRunningJob;
	}
	/**
	 * 获取服务器名称和 端口
	 * @return
	 */
	public static String getServerName(){
		if(serverName == null){
			serverName = RivuTools.getServerName() ;
		}
		return serverName ;
	}
	
	public static String getVData(String orgi){
		String vdata = (String) CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("com.rivues.vdata.data", orgi) ; 
		return vdata!=null ? vdata : "#data" ;
	}
	public static String getVMeasureData(String orgi){
		String vdata = (String) CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("com.rivues.vdata.measure.data", orgi) ; 
		return vdata!=null ? vdata : "#data" ;
	}
}
